/*******************************************************************************
**
** Copyright (c) 2011 - The OWE Team
**
** This file is part of OWE.
**
** OWE is a free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; version
** version 2.1 of the License.
**
** OWE is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with OWE. If not, see <http://www.gnu.org/licenses/>.
**
*******************************************************************************/

#ifndef USTRING_H
#define USTRING_H

#include <iostream>

#include <owe/global.h>

OWE_BEGIN_NAMESPACE

class UStringPrivate;

/*!
    \class UString
    \brief UTF-8 string handler.

    \ingroup Utils

    This class abstract the platform handling of UTF-8 strings. ASCII is also
    supported due to backwards compatibility.
*/
class OWE_EXPORT UString
{
public:
    /*!
        Constructs a new UString based on \a str buffer. Note that a UTF-8 null
        terminated buffer is expected as input.
    */
    UString(const char *str = 0);

    /*!
        Destructs the object releasing all allocated resources.
    */
    ~UString();

    /*!
        Create a copy of \a other.
    */
    UString(const UString &other);

    /*!
        Assigns the value of \a other to this object.
    */
    UString &operator=(const UString &other);

    /*!
        Check whenever the string contents is equals to another UTF-8 string
        array. This method is lexical aware and should ignore case. Returns 0 if
        strings are the same, and other number in the semantics of strcmp().
    */
    int compare(const char *uchar) const;

    /*!
        Concatenate \a ustr to the end of the current string.
    */
    UString &append(const UString &ustr);

    /*!
        Returns the internal buffer of the string.
    */
    const char *data() const;

    /*!
        Returns the size of the string in characters.

        \note Due to the multi byte nature of UTF-8, the string size may (and
        probably) will be different from the size in bytes.
    */
    int size() const;

    /*!
        Returns the string without any trailing and leading whitespaces. Also
        converts any sequence of whitespaces into one single space.
    */
    UString &simplified();

private:
    UStringPrivate *d_ptr;
};

inline const UString operator+(const UString &left, const UString &right) {
    UString ret(left);
    return ret.append(right);
}

inline bool operator==(const UString &left, const UString &right) {
    return (left.compare(right.data()) == 0);
}

inline bool operator!=(const UString &left, const UString &right) {
    return !(left.compare(right.data()) == 0);
}

inline bool operator<(const UString &left, const UString &right) {
    return (left.compare(right.data()) < 0);
}

inline bool operator>(const UString &left, const UString &right) {
    return (left.compare(right.data()) > 0);
}

inline bool operator==(const UString &left, const char *right) {
    return (left.compare(right) == 0);
}

inline bool operator!=(const UString &left, const char *right) {
    return !(left.compare(right) == 0);
}

inline bool operator<(const UString &left, const char *right) {
    return (left.compare(right) < 0);
}

inline bool operator>(const UString &left, const char *right) {
    return (left.compare(right) > 0);
}

inline std::ostream &operator<<(std::ostream &left, const UString &right)
{
    return left << right.data();
}

OWE_END_NAMESPACE

#endif // USTRING_H
